package com.augurit.wf.common.service.impl;

import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipInputStream;

import org.dozer.DozerBeanMapper;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.jbpm.api.Execution;
import org.jbpm.api.ExecutionService;
import org.jbpm.api.HistoryService;
import org.jbpm.api.ProcessDefinition;
import org.jbpm.api.ProcessDefinitionQuery;
import org.jbpm.api.ProcessEngine;
import org.jbpm.api.ProcessInstance;
import org.jbpm.api.RepositoryService;
import org.jbpm.api.TaskQuery;
import org.jbpm.api.TaskService;
import org.jbpm.api.history.HistoryActivityInstance;
import org.jbpm.api.history.HistoryProcessInstance;
import org.jbpm.api.history.HistoryTask;
import org.jbpm.api.model.Activity;
import org.jbpm.api.model.Transition;
import org.jbpm.api.task.Task;
import org.jbpm.pvm.internal.el.Expression;
import org.jbpm.pvm.internal.history.model.HistoryTaskImpl;
import org.jbpm.pvm.internal.history.model.HistoryTaskInstanceImpl;
import org.jbpm.pvm.internal.model.ActivityImpl;
import org.jbpm.pvm.internal.model.ExecutionImpl;
import org.jbpm.pvm.internal.model.ProcessDefinitionImpl;
import org.jbpm.pvm.internal.task.TaskDefinitionImpl;
import org.jbpm.pvm.internal.task.TaskImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.orm.Page;

import com.augurit.common.base.form.Attachment;
import com.augurit.common.base.form.ResultForm;
import com.augurit.common.dao.SysMetaColumnDao;
import com.augurit.common.entity.SysMetaColumn;
import com.augurit.common.entity.SysMetaTable;
import com.augurit.common.system.service.org.IOmUserService;
import com.augurit.common.system.web.org.form.OmUserForm;
import com.augurit.common.util.lang.StringUtils;
import com.augurit.gzcgwsp.wfex.common.service.IWfServiceEX;
import com.augurit.wf.bi.convert.WfBusInstanceConvertor;
import com.augurit.wf.bi.service.IWfBusInstanceService;
import com.augurit.wf.bi.service.IWfBusTemplateService;
import com.augurit.wf.bi.service.IWfViewConfigService;
import com.augurit.wf.bi.web.form.WfBusInstanceForm;
import com.augurit.wf.bi.web.form.WfBusInstanceTaskForm;
import com.augurit.wf.bi.web.form.WfBusTemplateForm;
import com.augurit.wf.bi.web.form.WfViewConfigForm;
import com.augurit.wf.client.agency.service.IWfAgencyService;
import com.augurit.wf.common.constant.MsgConstant;
import com.augurit.wf.common.constant.WfConstant;
import com.augurit.wf.common.dao.Jbpm4HistTaskDao;
import com.augurit.wf.common.dao.Jbpm4ParticipantDao;
import com.augurit.wf.common.dao.Jbpm4TaskDao;
import com.augurit.wf.common.dao.SMToSendDao;
import com.augurit.wf.common.dao.WfBusTemplateDao;
import com.augurit.wf.common.entity.Jbpm4HistProcinst;
import com.augurit.wf.common.entity.Jbpm4HistTask;
import com.augurit.wf.common.entity.Jbpm4Task;
import com.augurit.wf.common.entity.SMToSend;
import com.augurit.wf.common.entity.WfAgency;
import com.augurit.wf.common.entity.WfBusInstance;
import com.augurit.wf.common.form.TraceRecord;
import com.augurit.wf.common.form.WfBusBaseEntity;
import com.augurit.wf.common.form.WfSendMessageForm;
import com.augurit.wf.common.form.jbpm.ActivityForm;
import com.augurit.wf.common.service.IWfService;
import com.augurit.wf.common.util.ViewConfigCompiler;
import com.augurit.wf.common.util.WfUtils;
import com.augurit.wf.common.web.WfBusTemplateViewConfig;
import com.augurit.wf.jbpmex.assignee.IAssigneeParser;
import com.augurit.wf.jbpmex.task.AssigneeRangeHandler;
import com.augurit.wf.jbpmex.task.FreeFlowDefinition;
import com.augurit.wf.jbpmex.task.multitask.MultiTaskDefinition;

@Service
@Transactional
public class WfServiceImpl implements IWfService {
	
	
	@Autowired
	private ProcessEngine processEngine;
	
	@Autowired
	private WfBusTemplateDao wfBusTemplateDao;
	
	@Autowired
	private Jbpm4TaskDao jbpm4TaskDao;
	
	@Autowired
	private Jbpm4HistTaskDao jbpm4HistTaskDao;
	
	@Autowired
	private SysMetaColumnDao sysMetaColumnDao;
	
	@Autowired
	private IWfBusTemplateService wfBusTemplateService;
	
	@Autowired
	private IWfBusInstanceService wfBusInstanceService;
	
	@Autowired
	private IWfViewConfigService wfViewConfigService;
	
	@Autowired
	private DozerBeanMapper dozer;
	
	@Autowired
	private IAssigneeParser assigneeParser;
	
	@Autowired
	private IWfAgencyService wfAgencyService;
	
	@Autowired
	private Jbpm4ParticipantDao participantDao;
	@Autowired
	private IWfServiceEX wfServiceEX;

	@Autowired
	private SMToSendDao sMToSendDao;
	
	@Autowired
	private IOmUserService omUserService;
	
	/**
	 * 获取流程定义key对应的最新版本
	 * @param procDefKey
	 * @return
	 */
	public Integer getLastVersion(String procDefKey){
		List<ProcessDefinition> list = this.getProcDefByProcDefKey(procDefKey);
		if(list == null || list.size() == 0){
			throw new RuntimeException("Not exist key: " + procDefKey + " process definition");
		}
		return list.get(0).getVersion();
	}
	
	/**
	 * 起草阶段，根据templateCode设置流程实体的运行信息
	 * @param instance 
	 * @param templateCode
	 * @return
	 */
	public WfBusInstanceTaskForm setInstanceRunInfoByTemplateCode(WfBusInstanceTaskForm instance, final String templateCode){
		WfBusTemplateForm template = wfBusTemplateService.getByTemplateCode(templateCode);
		
		if(template == null){
			throw new RuntimeException("Can't find template by templateCode:" + template.getTemplateCode());
		}
		instance.setTemplateCode(templateCode);
		instance.setVersion(template.getWfDefVersion());
		
		String procDefId = WfUtils.convertToProcessDefinitionId(template.getWfDefKey(), template.getWfDefVersion());
		instance.setActivityName(this.getStartTaskActivityName(procDefId));
		
		return instance;
	}
	
	/**
	 * 根据taskInstDbid设置流程实体的运行信息
	 * @param instance 
	 * @param logineUserName
	 * @return
	 */
	public WfBusInstanceTaskForm setInstanceRunInfoByTaskId(WfBusInstanceTaskForm instance, final String logineUserName){
		WfBusInstanceTaskForm curInstance = this.getWfBusInstanceTaskById(instance.getTaskInstDbid(), logineUserName);
		if(curInstance == null){
			throw new RuntimeException("Can't find process instance by taskInstDbid:" + instance.getTaskInstDbid());
		}
		instance.setTemplateCode(curInstance.getTemplateCode());
		instance.setVersion(this.getProcDefByTaskInstDbid(curInstance.getTaskInstDbid()).getVersion());
		instance.setActivityName(curInstance.getActivityName());
		return instance;
	}
	
	/**
	 * 根据wfBusInstanceId设置流程实体的运行信息
	 * @param instance 
	 * @return
	 */
	public WfBusInstanceTaskForm setInstanceRunInfoByWfInstancId(WfBusInstanceTaskForm instance){
		WfBusInstanceTaskForm curInstance = this.getWfBusInstanceById(instance.getWfBusInstanceId());
		if(instance == null){
			throw new RuntimeException("Can't find process instance by wfBusInstanceId:" + instance.getTaskInstDbid());
		}
		instance.setTemplateCode(curInstance.getTemplateCode());
		instance.setVersion(this.getProcDefByProcInstId(curInstance.getProcInstId()).getVersion());
		instance.setActivityName(null);
		return instance;
	}
	
	public void wfDraft(String templateCode, WfBusInstanceTaskForm instance){
		if(templateCode != null && templateCode.trim().length() > 0 && instance != null){
			WfBusTemplateForm template = wfBusTemplateService.getByTemplateCode(templateCode);
			String activityName = this.getStartTaskActivityName(
					WfUtils.convertToProcessDefinitionId(template.getWfDefKey(), template.getWfDefVersion()));
			instance.setActivityName(activityName);
		}
	}
	
	/**
	 * 根据流程key和流程版本号获取流程定义
	 * @param procDefKey
	 * @param version
	 * @return
	 */
	public ProcessDefinition getProcDefByProcDefKeyAndVersion(String procDefKey, Integer version){
		return this.getProcDefByProcDefId(WfUtils.convertToProcessDefinitionId(procDefKey, version));
	}
	
	public <T extends WfBusBaseEntity> WfBusInstanceTaskForm wfBusStart(String templateCode, T form, String startWfUserKey, Map<String, Object> variables){
		
			//根据模板编号获取启动流程的必要信息
			WfBusTemplateForm wfBusTemplateForm = wfBusTemplateService.getByTemplateCode(templateCode);
			Long templateId = wfBusTemplateForm.getId();
			String masterEntity = wfBusTemplateForm.getMasterEntity();
			String wfDefKey = wfBusTemplateForm.getWfDefKey();
			Integer wfDefVersion = wfBusTemplateForm.getWfDefVersion();
			
			//判断是否具有启动流程权限
			if(wfBusTemplateForm != null && hasStartPriv(startWfUserKey, wfDefKey, wfDefVersion)){
				
				//初始化流程变量
				Map<String, Object> params = new HashMap<String, Object>();
				params.put(WfConstant.VAR_SYS_STARTER, startWfUserKey);
				
				if(variables != null && variables.size() > 0){
					params.putAll(variables);
				}
				
				//启动流程实例
				ProcessInstance processInstance = this.startProcessInstance(wfDefKey, wfDefVersion, params);
				
				if(processInstance != null){
					
					//建立业务和流程关联关系
					WfBusInstanceForm inst = new WfBusInstanceForm();
					inst.setMasterEntity(masterEntity);
					inst.setMasterEntityKey(form.getId().toString());
					inst.setProcInstId(processInstance.getId());
					inst.setTemplateId(templateId);
					WfUtils.syncSummary(form, inst, dozer);
					wfBusInstanceService.save(inst);

					
					TaskImpl task = (TaskImpl)this.getUniquePersonalTask(processInstance.getId(), startWfUserKey);
					if(task != null){
						WfBusInstanceTaskForm result = new WfBusInstanceTaskForm();
						result.setMasterEntity(masterEntity);
						result.setMasterEntityKey(form.getId().toString());
						result.setProcInstId(processInstance.getId());
						result.setTaskInstDbid(task.getDbid());
						return result;
					}
				}
			}
		return null;
	}
	
	public WfBusInstanceTaskForm wfBusStart(WfBusTemplateForm template, Map<String, ?> map, String startWfUserKey, Map<String, Object> variables){
		
		if(template != null){
			Long templateId = template.getId();
			String masterEntity = template.getMasterEntity();
			String wfDefKey = template.getWfDefKey();
			Integer wfDefVersion = template.getWfDefVersion();
			
			//判断是否具有启动流程权限
			if(hasStartPriv(startWfUserKey, wfDefKey, wfDefVersion)){
				
				//初始化流程变量
				Map<String, Object> params = new HashMap<String, Object>();
				params.put(WfConstant.VAR_SYS_STARTER, startWfUserKey);
				
				if(variables != null && variables.size() > 0){
					params.putAll(variables);
				}
				
				//启动流程实例
				ProcessInstance processInstance = this.startProcessInstance(wfDefKey, wfDefVersion, params);
				
				if(processInstance != null){
					
					//建立业务和流程关联关系
					WfBusInstanceForm inst = new WfBusInstanceForm();
					inst.setMasterEntity(masterEntity);
					inst.setMasterEntityKey(map.get("ID").toString());
					inst.setProcInstId(processInstance.getId());
					inst.setTemplateId(templateId);
					
					WfUtils.syncSummary(map, inst, dozer);
					
					wfBusInstanceService.save(inst);
	
					
					TaskImpl task = (TaskImpl)this.getUniquePersonalTask(processInstance.getId(), startWfUserKey);
					if(task != null){
						WfBusInstanceTaskForm result = new WfBusInstanceTaskForm();
						result.setMasterEntity(masterEntity);
						result.setMasterEntityKey(map.get("ID").toString());
						result.setProcInstId(processInstance.getId());
						result.setTaskInstDbid(task.getDbid());
						return result;
					}
				}
			}
		}
		return null;
	}
	
	public WfBusInstanceTaskForm getWfBusInstanceById(Long wfBusInstanceId){
		if(wfBusInstanceId != null){
			String hql = "select instance, temp.templateCode, temp.templateName from WfBusInstance instance, WfBusTemplate temp where instance.templateId = temp.id and instance.wfBusInstanceId = ?";
			Object[] objs = wfBusTemplateDao.findUnique(hql, wfBusInstanceId);
			WfBusInstanceTaskForm taskForm = WfBusInstanceConvertor.convertVoToTaskForm((WfBusInstance)objs[0]);
			taskForm.setTemplateCode((String)objs[1]);
			taskForm.setTemplateName((String)objs[2]);
			return taskForm;
		}
		return null;
	}
	
	/**
	 * 根据deploymentId获取流程定义
	 * @param deploymentId 
	 */
	@Transactional(readOnly = true)
	public ProcessDefinition getProcDefByDeploymentId(String deploymentId){
		RepositoryService repositoryService = processEngine.getRepositoryService();
		return repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).uniqueResult();
	}
	
	/**
	 * 从当前类路径中的XML文件中部署流程定义
	 * @param processDefFilePath 流程定义文件路径
	 * @return
	 */
	public String deployByXmlFileFromClasspath(String processDefFilePath){
		RepositoryService repositoryService = processEngine.getRepositoryService();
		return repositoryService.createDeployment().addResourceFromClasspath(processDefFilePath).deploy();
	}
	
	/**
	 * 从客户端上传的XML文件部署流程定义
	 * @param attachment 附件
	 * @return
	 */
	public String deployByXmlFileFromAttachment(Attachment attachment){
		RepositoryService repositoryService = processEngine.getRepositoryService();
		return repositoryService.createDeployment().addResourceFromFile(attachment.getFileFileName(), attachment.getFile()).deploy();
	}
	
	/**
	 * 从客户端上传的zip文件中(zip文件包含流程定义xml文件、流程图png文件)部署流程定义
	 * @param attachment 附件
	 * @return
	 * @throws Exception
	 */
	public String deployByZipFileFromAttachment(Attachment attachment)throws Exception{
		ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(attachment.getFile()));
		RepositoryService repositoryService = processEngine.getRepositoryService();
		return repositoryService.createDeployment().addResourcesFromZipInputStream(zipInputStream).deploy();
	}
	

	
	/**
	 * 根据流程定义key、流程版本号和资源类型获取其对应的资源
	 * @param processDefKey 流程定义key
	 * @param version 流程版本
	 * @param resourceType 资源类型 包括xml(流程定义xml)、png(流程定义图)
	 * @return
	 */
	@Transactional(readOnly = true)
	private InputStream getProcResourceAsStream(String processDefinitionId, String resourceType){
		RepositoryService repositoryService = processEngine.getRepositoryService();
		ProcessDefinitionImpl processDefinition = this.getProcDefByProcDefId(processDefinitionId);
		
		Set<String> resourceNames = repositoryService.getResourceNames(processDefinition.getDeploymentId());
		for (String resourceName :resourceNames) {
			if (resourceName.indexOf(resourceType) != -1) {
			    return repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), resourceName);
			}
		}
		
//		processEngine.getExecutionService().findProcessInstanceById("").getProcessDefinitionId()
		
		return null;
	}
	
	/**
	 * 根据流程定义key和流程版本号获取其对应的xml文件流
	 * @param processDefKey 流程定义key
	 * @param version	流程版本
	 * @return InputStream 文件流
	 */
	@Transactional(readOnly = true)
	public InputStream getProcDefXmlFileAsStream(String processDefKey, Integer version){
		return this.getProcResourceAsStream(
				WfUtils.convertToProcessDefinitionId(processDefKey, version), WfConstant.JPDL_XML);
	}
	

	
	/**
	 * 根据流程实例id获取其流程图对应的png文件流
	 * @param processInstanceId 流程实例id
	 * @return InputStream 文件流
	 */
	@Transactional(readOnly = true)
	public InputStream getProcDiagramPngFileAsStream(String processInstanceId){
		ExecutionService executionService = processEngine.getExecutionService();
		ProcessInstance processInstance = executionService.findProcessInstanceById(processInstanceId);
		
		return this.getProcResourceAsStream(processInstance.getProcessDefinitionId(), WfConstant.JPDL_PNG);
	}
	
	/**
	 * 这个方法有问题
	 * 获取流程实例所处的流程结点名称
	 * @param processInstanceId 流程实例id
	 * @return
	 */
	@Transactional(readOnly = true)
	public String getActivityNameOfProcessInstance(String processInstanceId){
		ExecutionService executionService = processEngine.getExecutionService();
		ProcessInstance processInstance = executionService.findProcessInstanceById(processInstanceId);
		if(processInstance != null)
			return  processInstance.findActiveActivityNames().iterator().next();
		return null;
	}

	/**
	 * 根据流程定义key和流程版本号获取其对应的流程实例
	 * @param processDefKey 流程定义key
	 * @param version 流程版本
	 * @return 流程实例列表
	 */
	@Transactional(readOnly = true)
	public List<ProcessInstance> getAllProcessInstances(String processDefKey, Integer version){
		ExecutionService executionService = processEngine.getExecutionService();
		return executionService.createProcessInstanceQuery().processDefinitionId(WfUtils.convertToProcessDefinitionId(processDefKey, version)).list();
	}
	
	/**
	 * 根据流程定义Id获取其对应的流程实例
	 * @param processDefId 流程定义Id
	 * @return 流程实例列表 
	 */
	@Transactional(readOnly = true)
	public List<ProcessInstance> getProcInstsByTemplateId(Long wfTemplateId){
		if(wfTemplateId != null){
			WfBusTemplateForm form = this.wfBusTemplateService.get(wfTemplateId);
			if(form != null)
				return getAllProcessInstances(form.getWfDefKey(),form.getWfDefVersion());
		}
		return null;
	}
	
	/**
	 * 删除流程指定版本，并级联删除其对应的流程实例
	 * @param processDefKey 流程定义key
	 * @param version 流程版本
	 */
	public void deleteProcessVersionCascade(String processDefKey, Integer version){
		RepositoryService repositoryService = processEngine.getRepositoryService();
		ProcessDefinition proccessDef = repositoryService.createProcessDefinitionQuery().processDefinitionId(WfUtils.convertToProcessDefinitionId(processDefKey, version)).uniqueResult();
		repositoryService.deleteDeploymentCascade(proccessDef.getDeploymentId());
	}
	
	/**
	 * 启动流程实例
	 * @param processDefKey 流程定义KEY
	 * @param variables 变量
	 * @return
	 */
	public ProcessInstance startProcessInstance(String processDefKey, Integer wfDefVersion, Map<String, ?> variables) {
		ExecutionService executionService = processEngine.getExecutionService();//----流程执行服务接口
		
		if(wfDefVersion != null){
			if(variables != null && variables.size() > 0)
				return executionService.startProcessInstanceById(WfUtils.convertToProcessDefinitionId(processDefKey, wfDefVersion), variables);
			else
				return executionService.startProcessInstanceById(WfUtils.convertToProcessDefinitionId(processDefKey, wfDefVersion));
		}else{
			if(variables != null && variables.size() > 0)
				return executionService.startProcessInstanceByKey(processDefKey, variables);
			else
				return executionService.startProcessInstanceByKey(processDefKey);
		}
	}

	/**
	 * 同步任务办理意见至历史任务
	 */
	public void syncTaskOpinionToHisTask(String taskId){
		if(taskId != null){
			TaskService taskService = processEngine.getTaskService();
			taskService.syncOpinionToHisTask(taskId);
		}
	}
	
	/**
	 * 根据ID获取任务对象
	 * @param taskInstDbid
	 * @return
	 */
	public Jbpm4Task getJbpm4TaskById(Long taskInstDbid){
		if(taskInstDbid != null)
			return this.jbpm4TaskDao.findUniqueBy("taskInstDbid", taskInstDbid);
		else
			return null;
	}
	
	/**
	 * 保存任务签收时间至历史任务
	 */
	public void signTask(Long taskInstDbid){
		Jbpm4Task task = getJbpm4TaskById(taskInstDbid);
		signTask(task);
	}
	
	/**
	 * 保存任务签收时间至历史任务
	 */
	public void signTasks(Long[] taskInstDbids){
		if(taskInstDbids != null && taskInstDbids.length > 0){
			for(Long taskInstDbid : taskInstDbids){
				this.signTask(taskInstDbid);
			}
		}
	}
	
	/**
	 * 保存任务签收时间至历史任务
	 */
	public void signTask(Jbpm4Task task){
		if(task != null){
			
			//签收时间
			if(task.getSignTime()== null){
				Date date = new Date();
				task.setSignTime(date);
				this.jbpm4TaskDao.save(task);
				
				//同步HistoryTask的签收时间
				syncSignTimeToHisTask(task, date);
				
				//同步至任务汇总表
//				wfTaskSummaryService.signSummaryTask(task.getTaskInstDbid());
			}
		}
	}
	
	/**
	 * 同步任务签收时间至历史任务
	 */
	private void syncSignTimeToHisTask(Jbpm4Task task, Date date){
		if(task != null && date != null){
			Jbpm4HistTask jbpm4HistTask = jbpm4HistTaskDao.get(task.getTaskInstDbid());
			jbpm4HistTask.setSignTime(date);
			jbpm4HistTaskDao.save(jbpm4HistTask);
		}
	}
	
	/**
	 * 完成指定任务
	 * @param taskInstDbid 任务ID
	 */
	public void completeTask(String taskInstDbid){
		if(taskInstDbid != null && taskInstDbid.trim().length() > 0)
			processEngine.getTaskService().completeTask(taskInstDbid);
	}
	
	/**
	 * 根据流程业务实例ID获取流程业务实例对象
	 * @param wfBusInstanceId 流程业务实例ID
	 */
	@Transactional(readOnly = true)
	public WfBusInstanceTaskForm getWfBusInstanceTask(Long wfBusInstanceId){
		String hql = "select instance, task from WfBusInstance instance, Jbpm4Task task where instance.wfInstanceId=task.executionId and instance.wfBusInstanceId=?";
		Object[] objs = wfBusTemplateDao.findUnique(hql, wfBusInstanceId);
		
		if(objs != null && objs.length > 0){

			WfBusInstanceTaskForm form = new WfBusInstanceTaskForm();
				
			WfBusInstance instance = (WfBusInstance)objs[0];
			Jbpm4Task task = (Jbpm4Task)objs[1];
				
			dozer.map(instance, form);
			dozer.map(task, form);		
			
			return form;
		}else
			return null;
	}
	/**
	 * 根据流程业务实例ID获取流程业务实例对象
	 * @author 舒军添加
	 * @param wfBusInstanceId 流程业务实例ID
	 */
	public WfBusInstanceTaskForm getWfBusInstanceTaskById(Long taskInstDbid, String userKey){
		if(taskInstDbid != null && userKey != null && userKey.trim().length() > 0){
			
			String hql = "select instance, task, template.templateName, template.templateCode from WfBusTemplate template, " +
					" WfBusInstance instance, Jbpm4Task task, HistoryProcessInstanceImpl procInst" +
					" where template.id=instance.templateId " +
					" and instance.procInstId=procInst.processInstanceId " +
					" and task.procinst=procInst.dbid and task.taskInstDbid=?";
			Object[] objs = wfBusTemplateDao.findUnique(hql, taskInstDbid);
			
			if(objs != null && objs.length > 0){
		
				WfBusInstance instance = (WfBusInstance)objs[0];
				Jbpm4Task task = (Jbpm4Task)objs[1];
				String templateName = (String)objs[2];
				String templateCode = (String)objs[3];
				
				if(WfUtils.isValidAssignee(task, userKey)){
					WfBusInstanceTaskForm form = new WfBusInstanceTaskForm();
					
					dozer.map(instance, form);
					dozer.map(task, form);
					form.setTemplateName(templateName);
					form.setTemplateCode(templateCode);
					form.setVersion(this.getProcDefByTaskInstDbid(taskInstDbid).getVersion());
					
					this.signTask(task);
					return form;
				}
			}
		}
		return null;
	}
	
	/**
	 * 获取指定流程实例的指定用户的未签收或处理中的任务列表
	 * @param executionId
	 * @param userKey
	 * @return
	 */
	public List<Task> getPersonalTasks(String executionId, String userKey){
		if(executionId != null && userKey != null){
			TaskService taskService = processEngine.getTaskService();
			return taskService.createTaskQuery()
					.processInstanceId(executionId).assignee(userKey).list();
		}
		return null;
	}
	
	/**
	 * 获取指定流程实例的指定用户的未签收或处理中的任务列表
	 * @param executionId
	 * @param userKey
	 * @return
	 */
	public Task getUniquePersonalTask(String executionId, String userKey){
		if(executionId != null && userKey != null){
			TaskService taskService = processEngine.getTaskService();
			
			//test start
			TaskQuery qu = taskService.createTaskQuery();
			qu.processInstanceId(executionId);
			qu.assignee(userKey);
			List<Task> list = qu.list();
			//test end
			//List<Task> list = taskService.createTaskQuery().processInstanceId(executionId).assignee(userKey).list();
			if(list != null && list.size() == 1)
				return list.get(0);
		}
		return null;
	}
	
	/**
	 * 根据用户标识获取指定用户的流程业务实例对象
	 * @param userKey 用户标识
	 */
	@Transactional(readOnly = true)
	public List<WfBusInstanceTaskForm> getPersonalTasks(String userKey){
		String hql = "select instance, task from WfBusInstance instance, Jbpm4Task task where instance.procInstId=task.executionId and task.state='" + TaskImpl.STATE_OPEN + "' and task.assignee=?";
		List<Object[]> list = wfBusTemplateDao.find(hql, userKey);
		
		if(list != null && list.size() > 0){
			List<WfBusInstanceTaskForm> result = new ArrayList<WfBusInstanceTaskForm>();
			
			for(Object[] objs : list){
				WfBusInstanceTaskForm form = new WfBusInstanceTaskForm();
				
				WfBusInstance instance = (WfBusInstance)objs[0];
				Jbpm4Task task = (Jbpm4Task)objs[1];
				
				dozer.map(instance, form);
				dozer.map(task, form);
				
				result.add(form);
			}
			
			return result;
		}else
			return null;
	}
	
	/**
	 * 获取指定流程业务模板的待办列表
	 */
	public void loadDbTasksWithBusInfo(Page page, String templateCode, String userKey, Map<String, String> params){
		loadPersonalTasksWithBusInfo(page, templateCode, userKey, true, params);
	}
	
	public void loadZbTasksWithBusInfo(Page page, String templateCode, String userKey, Map<String, String> params){
		loadPersonalTasksWithBusInfo(page, templateCode, userKey, false, params);
	}
	
	public void loadDZbTasksWithBusInfo(Page page, String templateCode, String userKey, Map<String, String> params){
		loadPersonalTasksWithBusInfo(page, templateCode, userKey, null, params);
	}
	
	private Long countResult(String sql, Map values){
		String countSql = "select count(*) from (" + sql + ")";
		SQLQuery countQuery = wfBusTemplateDao.getSession().createSQLQuery(countSql);
		countQuery.setProperties(values);
		BigDecimal obj = (BigDecimal)countQuery.uniqueResult();
		return obj.longValue();
	}
	
	/**
	 * 获取待办或在办或待在办任务列表
	 * @param page
	 * @param templateCode
	 * @param userKey
	 * @param isDb true表示待办，false表示在办，null表示待在办
	 * @param params
	 */
	private void loadPersonalTasksWithBusInfo(Page page, String templateCode, String userKey, Boolean isDb, Map<String, String> params){

		WfViewConfigForm viewConfig = wfViewConfigService.getByTemplateCode(templateCode);

		String groupBy = params.get("groupBy");
		String groupDir = params.get("groupDir");
		
		String hql = "select distinct " 
					+ viewConfig.getKeyProperty() + " as id " + ViewConfigCompiler.PROP_SEPARATOR
					+ "jbpm4Task.agent_name as agentName, jbpm4Task.duedate_ as duedate, jbpm4Task.assignee_name as assigneeName, jbpm4Task.agent_start_date as agentStartDate, jbpm4Task.agent_end_date as agentEndDate, jbpm4Task.create_ as create_, jbpm4Task.sign_time as signTime , wfInstance.wf_bus_instance_id as wfBusInstanceId, wfInstance.proc_inst_id as procInstId, jbpm4Task.dbid_ as taskInstDbid, procInst.start_ asstartTime, procInst.process_duedate as processDuedate," 
					+ viewConfig.getListProperties()
					+ " from " + viewConfig.getSelectEntities() + ", wf_bus_instance wfInstance, wf_bus_template temp, jbpm4_hist_procinst procInst,jbpm4_task jbpm4Task"
					+ " where " + (viewConfig.getEntitiesJoinClause() == null ? "" : viewConfig.getEntitiesJoinClause())
					+ viewConfig.getKeyProperty() + "=wfInstance.master_entity_key and wfInstance.proc_inst_id=procInst.id_ and jbpm4Task.procinst_=procInst.dbid_ and wfInstance.template_id=temp.id and temp.template_code=:templateCode and jbpm4Task.state_=:jbpmTaskState"
					+ " and (jbpm4Task.assignee_=:jbpmTaskAssignee or (jbpm4Task.agent=:jbpmTaskAssignee and jbpm4Task.agent_start_date<:now and jbpm4Task.agent_end_date>:now))";
		
		if(isDb != null){
			hql += isDb ? " and jbpm4Task.sign_time is null" : " and jbpm4Task.sign_time is not null";
		}
		
		Map<String, Object> values = new HashMap();
		
		if(viewConfig.getWhereClause() != null && viewConfig.getWhereClause().trim().length() > 0 && params != null){

			//清除无效参数
			ViewConfigCompiler.clearUseLessParam(params);
			
			
			//计算实际要查询的参数值
			String masterEntity = ViewConfigCompiler.findBusEntityName(viewConfig.getSelectEntities());
			List<SysMetaColumn> queryColumns = getSysMetaColumns(viewConfig.getQueryProperties(), masterEntity);
			
			Map<String, Object> objParams = ViewConfigCompiler.convertToObjectMap(params, queryColumns);
			if(objParams != null && objParams.size() > 0)
				values.putAll(objParams);
			
			
			//解析WHERE语句并生成符合实际查询条件的WHERE子句
			String whereClause = ViewConfigCompiler.parseWhereClause(viewConfig.getWhereClause(), viewConfig.getWhereLogic(), objParams);
			if(whereClause != null && whereClause.trim().length() > 0){
				hql += " and (" + whereClause + ")";
			}
		}
		
		values.put("templateCode", templateCode);
		values.put("jbpmTaskState", TaskImpl.STATE_OPEN);
		values.put("jbpmTaskAssignee", userKey);
		values.put("now", new Date());
		
		page.setTotalCount(countResult(hql, values));
		
		// 排序
		hql += ViewConfigCompiler.addSortClause(groupBy, groupDir, page.getOrderBy(), page.getOrder(), viewConfig);
		
		

		//wfBusTemplateDao.findPage(page, hql, values);
		SQLQuery query = wfBusTemplateDao.getSession().createSQLQuery(hql);
		
		query.setProperties(values);
		query.setFirstResult(page.getFirst() - 1);
		query.setMaxResults(page.getPageSize());
		page.setResult(query.list());
		
	}
	
	
	
	public void loadYbTasksWithBusInfo(Page page, String templateCode, String userKey, Map<String, String> params){
		WfViewConfigForm viewConfig = wfViewConfigService.getByTemplateCode(templateCode);

		String groupBy = params.get("groupBy");
		String groupDir = params.get("groupDir");
		
		String hql = "select distinct "
		+ viewConfig.getKeyProperty() + ViewConfigCompiler.PROP_SEPARATOR
		+ "wfInstance.wf_bus_instance_id as wfBusInstanceId, wfInstance.proc_inst_id as procInstId,temp.template_code as templateCode," 
		+ viewConfig.getListProperties()
		+ " from " + viewConfig.getSelectEntities() + ", wf_bus_instance wfInstance, wf_bus_template temp, jbpm4_hist_actinst jbpm4HistActInst, jbpm4_hist_procinst Jbpm4HistProcinst , jbpm4_hist_task jbpm4HistTask"
		+ " where " + (viewConfig.getEntitiesJoinClause() == null ? "" : viewConfig.getEntitiesJoinClause())
		+ viewConfig.getKeyProperty() + "=wfInstance.master_entity_key and wfInstance.proc_inst_id=jbpm4HistProcinst.id_" 
		+ " and jbpm4HistProcinst.dbid_=jbpm4HistActInst.HPROCI_ and jbpm4HistActInst.HTASK_=jbpm4HistTask.DBID_" 
		+ " and wfInstance.template_id=temp.id and jbpm4HistActInst.type_=:jbpm4HistActInstType and temp.template_code=:templateCode"
		+ " and jbpm4HistProcinst.state_=:jbpm4HistProcinstState and jbpm4HistTask.state_=:jbpmTaskState and jbpm4HistTask.assignee_=:jbpmTaskAssignee";
		
		
		Map<String, Object> values = new HashMap<String, Object>();
		
		if(viewConfig.getWhereClause() != null && viewConfig.getWhereClause().trim().length() > 0 && params != null){

			ViewConfigCompiler.clearUseLessParam(params);
			
			String masterEntity = ViewConfigCompiler.findBusEntityName(viewConfig.getSelectEntities());
			List<SysMetaColumn> queryColumns = getSysMetaColumns(viewConfig.getQueryProperties(), masterEntity);
			
			Map<String, Object> objParams = ViewConfigCompiler.convertToObjectMap(params, queryColumns);
			if(objParams != null && objParams.size() > 0)
				values.putAll(objParams);
			
			
			//解析WHERE语句并生成符合实际查询条件的WHERE子句
			String whereClause = ViewConfigCompiler.parseWhereClause(viewConfig.getWhereClause(), viewConfig.getWhereLogic(), objParams);
			if(whereClause != null && whereClause.trim().length() > 0){
				hql += " and (";
				hql += whereClause;
				hql += ")";
			}
		}
		
		
		
		values.put("jbpm4HistActInstType", WfConstant.ACTIVITY_TYPE_TASK);
		values.put("templateCode", templateCode);
		values.put("jbpm4HistProcinstState", HistoryProcessInstance.STATE_ACTIVE);
		values.put("jbpmTaskState", TaskImpl.STATE_COMPLETED);
		values.put("jbpmTaskAssignee", userKey);
		
		page.setTotalCount(countResult(hql, values));;
		
		// 排序
		hql += ViewConfigCompiler.addSortClause(groupBy, groupDir, page.getOrderBy(), page.getOrder(), viewConfig);

		SQLQuery query = wfBusTemplateDao.getSession().createSQLQuery(hql);
		query.setProperties(values);
		query.setFirstResult(page.getFirst() - 1);
		query.setMaxResults(page.getPageSize());
		page.setResult(query.list());
		
	}
	
	public void loadBjTasksWithBusInfo(Page page, String templateCode, String userKey, Map<String, String> params){
		WfViewConfigForm viewConfig = wfViewConfigService.getByTemplateCode(templateCode);

		String groupBy = params.get("groupBy");
		String groupDir = params.get("groupDir");
		
		String hql = "select distinct "
					+ viewConfig.getKeyProperty() + ViewConfigCompiler.PROP_SEPARATOR
					+ "wfInstance.wf_bus_instance_id, wfInstance.proc_inst_id,temp.template_code," 
					+ viewConfig.getListProperties()
					+ " from " + viewConfig.getSelectEntities() + ", wf_bus_instance wfInstance, wf_bus_template temp,jbpm4_hist_actinst jbpm4HistActInst, jbpm4_hist_procinst jbpm4HistProcinst, jbpm4_hist_task jbpm4HistTask"
					+ " where " + (viewConfig.getEntitiesJoinClause() == null ? "" : viewConfig.getEntitiesJoinClause())
					+ viewConfig.getKeyProperty() + "=wfInstance.master_entity_key and wfInstance.proc_inst_id=jbpm4HistProcinst.ID_"
					+ " and jbpm4HistProcinst.DBID_=jbpm4HistActInst.HPROCI_ and jbpm4HistActInst.type_=:jbpm4HistActInstType and jbpm4HistActInst.HTASK_=jbpm4HistTask.DBID_ and wfInstance.template_id=temp.id and temp.template_code=:templateCode"
					+ " and jbpm4HistProcinst.state_=:jbpm4HistProcinstState and jbpm4HistTask.assignee_=:jbpmTaskAssignee";
		
		
		Map<String, Object> values = new HashMap();
		
		if(viewConfig.getWhereClause() != null && viewConfig.getWhereClause().trim().length() > 0 && params != null){

			ViewConfigCompiler.clearUseLessParam(params);
			
			String masterEntity = ViewConfigCompiler.findBusEntityName(viewConfig.getSelectEntities());
			List<SysMetaColumn> queryColumns = getSysMetaColumns(viewConfig.getQueryProperties(), masterEntity);
			
			Map<String, Object> objParams = ViewConfigCompiler.convertToObjectMap(params, queryColumns);
			if(objParams != null && objParams.size() > 0)
				values.putAll(objParams);
			
			//解析WHERE语句并生成符合实际查询条件的WHERE子句			
			String whereClause = ViewConfigCompiler.parseWhereClause(viewConfig.getWhereClause(), viewConfig.getWhereLogic(), objParams);
			if(whereClause != null && whereClause.trim().length() > 0){
				hql += " and (";
				hql += whereClause;
				hql += ")";
			}
		}
		
		values.put("jbpm4HistActInstType", WfConstant.ACTIVITY_TYPE_TASK);
		values.put("templateCode", templateCode);
		values.put("jbpm4HistProcinstState", HistoryProcessInstance.STATE_ENDED);
		values.put("jbpmTaskAssignee", userKey);

		page.setTotalCount(countResult(hql, values));
		
		// 排序
		hql += ViewConfigCompiler.addSortClause(groupBy, groupDir, page.getOrderBy(), page.getOrder(), viewConfig);

		SQLQuery query = wfBusTemplateDao.getSession().createSQLQuery(hql);
		
		query.setProperties(values);
		query.setFirstResult(page.getFirst() - 1);
		query.setMaxResults(page.getPageSize());
		page.setResult(query.list());
	}
	
	
	private  WfBusTemplateViewConfig loadViewConfig(WfViewConfigForm viewConfig){
		WfBusTemplateViewConfig templateViewConfig = new WfBusTemplateViewConfig();
		
		// 设置主键名称
		templateViewConfig.setKeyPropertyName(ViewConfigCompiler.getOnlyPropertyName(viewConfig.getKeyProperty()));
		
		// 设置默认的排序字段名称和排序方向
		templateViewConfig.setOrderPropertyName(ViewConfigCompiler.getOnlyPropertyName(viewConfig.getOrderProperty()));
		templateViewConfig.setOrderby(viewConfig.getOrderby());
		
		// 设置默认的分组字段
		templateViewConfig.setGroupPropertyName(ViewConfigCompiler.getOnlyPropertyName(viewConfig.getGroupProperty()));
		
		// 获取主业务实体名称
		String masterEntity = ViewConfigCompiler.findBusEntityName(viewConfig.getSelectEntities());
		
		// 设置查询条件字段
		List<SysMetaColumn> queryColumns = getSysMetaColumns(viewConfig.getQueryProperties(), masterEntity);
		if(queryColumns != null && queryColumns.size() > 0){
			templateViewConfig.getQueryPropertyList().addAll(
					ViewConfigCompiler.convertWfBusPropertyConfig(queryColumns));
		}
		
		// 设置表格列字段
		List<SysMetaColumn> listColumns = getSysMetaColumns(viewConfig.getListProperties(), masterEntity);
		if(listColumns != null && listColumns.size() > 0){
			templateViewConfig.getGridPropertyList().addAll(
					ViewConfigCompiler.convertWfBusPropertyConfig(listColumns));
		}

		return templateViewConfig;
	}
	public WfBusTemplateViewConfig loadViewConfig(Long templateId){
		// 获取视图配置对象
		WfViewConfigForm viewConfig = wfViewConfigService.getByTemplateId(templateId);
		return loadViewConfig(viewConfig);
	}
	
	/**
	 * 加载指定流程业务模板的待办视图配置
	 */
	public WfBusTemplateViewConfig loadViewConfig(String templateCode){
		// 获取视图配置对象
		WfViewConfigForm viewConfig = wfViewConfigService.getByTemplateCode(templateCode);
		return loadViewConfig(viewConfig);
	}
	
	/**
	 * 获取属性字符串中各属性的元数据定义
	 * @param propertiesStr
	 * @param masterEntity
	 * @return
	 */
	private List<SysMetaColumn> getSysMetaColumns(String propertiesStr, String masterEntity){
		if(propertiesStr != null && propertiesStr.trim().length() > 0){
			
			// 获取各字段解析字符串
			String[] propArray = propertiesStr.split(ViewConfigCompiler.PROP_SEPARATOR);
			
			// 存储属性名称，格式为“实体.属性名”，如“Notice.title”
			Map<String, SysMetaColumn> metaColumnMap = new LinkedHashMap(propArray.length);
			for(String prop : propArray){
				String propStr = ViewConfigCompiler.upperCaseFirstChar(prop);
				String key = propStr.replace("Bus.", masterEntity+".");
				metaColumnMap.put(key, null);
			}
			
			String whereClause = ViewConfigCompiler.convertToMetaQueryClause(metaColumnMap);
			if(whereClause != null){
				String hql = "from SysMetaTable t, SysMetaColumn c where t.id=c.tableId" + whereClause;
				List<Object[]> objsList = sysMetaColumnDao.find(hql);

				if(objsList != null && objsList.size() > 0){
					for(int i=0; i<objsList.size(); i++){
						Object[] objs = objsList.get(i);
						SysMetaTable table = (SysMetaTable)objs[0];
						SysMetaColumn column = (SysMetaColumn)objs[1];
						
						String key = table.getTableName() + "." + column.getColumnName();
						metaColumnMap.put(key, column);
					}
				}
				
				return ViewConfigCompiler.convertToMetaColumnList(metaColumnMap);
			}
		}
		return null;
	}
	
	/**
	 * 加载发送配置定义信息
	 */
	public void loadWfSendOption(WfBusInstanceTaskForm form){
		
		if(form != null && form.getTaskInstDbid() != null){
			
			//获取任务实例
			TaskService taskService = this.processEngine.getTaskService();
			Task curTask = taskService.getTask(form.getTaskInstDbid().toString());
			
			form.setActivityName(curTask.getActivityName());
			
			//当前任务是多工作项,不需要加载发送对话框信息
			if(WfUtils.isMultiTask(curTask)){
				form.setDirectSend(true);
			}
			//当前任务普通任务,加载发送对话框信息
			else{
				loadWfSendOptionByCommonTask(form);
				form.setDirectSend(false);
			}
		}
	}
	
	//普通任务的加载发送对话框信息
	public void loadWfSendOptionByCommonTask(WfBusInstanceTaskForm form){
		if(form != null && form.getTaskInstDbid() != null && form.getActivityName() != null){
			
			// 获取流程定义
			ProcessDefinitionImpl processDefinition = this.getProcDefByTaskInstDbid(form.getTaskInstDbid());
			ActivityImpl currActivityDefinition = processDefinition.findActivity(form.getActivityName());
			
			//加载流转信息
			// 处理人工流转
			this.loadNextTransitionsByCurrActivity(processDefinition, currActivityDefinition, form);
				
			// 加载自由流节点定义列表
			this.loadFreeActivitiesByCurrActivity(processDefinition, currActivityDefinition, form);
				
			//去掉自由流节点中包含的人工流转节点
			WfUtils.removeRepeatActivity(form);

			//计算第一个目标节点的发送选项
			String firstDestActivityName = form.getNextTransitions().get(0).getDestination().getName();
			calcWfSendOption(form, processDefinition, firstDestActivityName);
		}
	}
	
	/**
	 * 计算发送选项
	 * @param form
	 * @param destActivityName
	 */
	public void calcWfSendOption(WfBusInstanceTaskForm form){
		if(form != null && form.getTaskInstDbid() != null
				&& form.getDestActivityName() != null && form.getDestActivityName().trim().length() > 0){
			
			// 获取流程定义
			ProcessDefinitionImpl processDefinition = this.getProcDefByTaskInstDbid(form.getTaskInstDbid());

			//计算目标节点的发送选项
			String destActivityName = form.getDestActivityName();
			calcWfSendOption(form, processDefinition, destActivityName);
		}
	}
	
	/**
	 * 计算发送选项
	 * @param form
	 * @param processDefinition
	 */
	private void calcWfSendOption(WfBusInstanceTaskForm form, ProcessDefinitionImpl processDefinition, String destActivityName){
		if(form != null && processDefinition != null){
			
			TaskDefinitionImpl taskDefinition =  processDefinition.getTaskDefinition(destActivityName);
			
			if(taskDefinition != null){
				if(taskDefinition.getAssigneeRangeHandler() != null){
					taskDefinition.setAssigneeRange(this.calcAssigneeRange(taskDefinition.getAssigneeRangeHandler()));
					form.setNeedSelectAssignee(true);
				}
				else if(taskDefinition.getAssigneeRange() != null && taskDefinition.getAssigneeRange().trim().length() > 0){
					form.setNeedSelectAssignee(true);
				}
				else{
					form.setDefaultSendAssignees(this.getAssigneeNames(taskDefinition, form.getTaskInstDbid()));
				}
				form.setMessage(MsgConstant.getNextTaskMsg(taskDefinition));
			}
			else{
				form.setDefaultSendAssignees(null);
				form.setNeedSelectAssignee(false);
				form.setMessage(MsgConstant.SEND_TO_NEXT_ACTIVITY);
			}
		}
	}
	
	public ProcessDefinitionImpl getProcDefByJbpm4Task(Jbpm4Task jbpm4Task){
		if(jbpm4Task != null){
			return getProcDefByProcInstDbid(jbpm4Task.getProcinst());
		}else
			return null;
	}
	
	public ProcessDefinitionImpl getProcDefByTaskInstDbid(Long taskInstDbid){
		if(taskInstDbid != null){
			Jbpm4Task jbpm4Task = jbpm4TaskDao.get(taskInstDbid);
			return getProcDefByJbpm4Task(jbpm4Task);
		}else
			return null;
	}
	
	public ProcessDefinitionImpl getProcDefByProcInstId(String procInstId){
		if(procInstId != null && procInstId.trim().length() > 0){
			Execution execution = processEngine.getExecutionService().findExecutionById(procInstId);
			if(execution != null)
				return getProcDefByProcDefId(execution.getProcessDefinitionId());
			else{
				String hql = "select hist from  Jbpm4HistProcinst hist where hist.procInstId = ?";
				Jbpm4HistProcinst entity = jbpm4TaskDao.findUnique(hql, procInstId);
				return getProcDefByProcDefId(entity.getProcdefid());
			}
		}
		return null;
	}
	public ProcessDefinitionImpl getProcDefByProcInstDbid(Long procInstDbid){
		if(procInstDbid != null){
			String hql = "select hist from  Jbpm4HistProcinst hist where hist.procInstDbId = ?";
			Jbpm4HistProcinst entity = jbpm4TaskDao.findUnique(hql, procInstDbid);
			return getProcDefByProcDefId(entity.getProcdefid());
		}
		return null;
	}
	/**
	 * 根据流程定义ID获取流程定义
	 * @param processDefinitionId
	 * @return
	 */
	public ProcessDefinitionImpl getProcDefByProcDefId(String processDefinitionId){
		if (processDefinitionId != null && processDefinitionId.trim().length() > 0) {
			//根据流程引擎获取管理流程定义（发布流程、删除流程等）
			RepositoryService repositoryService = processEngine.getRepositoryService();
			return (ProcessDefinitionImpl) repositoryService.createProcessDefinitionQuery()
					.processDefinitionId(processDefinitionId).uniqueResult();
		}else
			return null;
	}
	
	/**
	 * 返回流程定义中开始（或第一个）人工节点
	 * 前提条件：流程定义的开始节点的下一节点只能是单个人工节点
	 * @param processDefinitionId
	 * @return
	 */
	public Activity getStartTaskActivity(String processDefinitionId){
		ProcessDefinitionImpl ProcessDefinition = this.getProcDefByProcDefId(processDefinitionId);
		ActivityImpl startActivity = ProcessDefinition.getInitial();
		ActivityImpl nextActivity = startActivity.getDefaultOutgoingTransition().getDestination();
		if(nextActivity != null && ProcessDefinition.getTaskDefinition(nextActivity.getName()) != null){
			return nextActivity;
		}
		return null;
	}
	
	/**
	 * 返回流程定义中开始（或第一个）人工节点名称
	 * 前提条件：流程定义的开始节点的下一节点只能是单个人工节点
	 * @param processDefinitionId
	 * @return
	 */
	public String getStartTaskActivityName(String processDefinitionId){
		Activity startTaskActivity = getStartTaskActivity(processDefinitionId);
		if(startTaskActivity != null)
			return startTaskActivity.getName();
		else
			return null;
	}
	
	/**
	 * 获取人工任务参与者范围定义
	 * @param taskInstDbid
	 * @param taskActivityName
	 * @return
	 */
	public String getAssigneeRange(Long taskInstDbid, String taskActivityName){
		if(taskInstDbid != null){
			TaskDefinitionImpl taskDefinition = this.getTaskDefinition(taskInstDbid, taskActivityName);
			if(taskDefinition != null && taskDefinition.getAssigneeRange() != null){
				return this.calcJbpmVarExpresssion(Expression.create(taskDefinition.getAssigneeRange()), taskInstDbid);
			}
		}
		return null;
	}
	
	public TaskDefinitionImpl getTaskDefinition(Long taskInstDbid, String taskActivityName){
		if(taskInstDbid != null && taskActivityName != null && taskActivityName.trim().length() > 0){
			
			ProcessDefinitionImpl processDefinition = getProcDefByTaskInstDbid(taskInstDbid);
			return processDefinition.getTaskDefinition(taskActivityName);
		}else
			return null;
	}
	
	public TaskDefinitionImpl getTaskDefinition(String wfInstanceId, String taskActivityName){
		if(wfInstanceId != null && wfInstanceId.trim().length() > 0 
				&& taskActivityName != null && taskActivityName.trim().length() > 0){
			
			ProcessDefinitionImpl processDefinition = getProcDefByProcInstId(wfInstanceId);
			return processDefinition.getTaskDefinition(taskActivityName);
		}else
			return null;
	}
	
	/**
	 * 加载当前节点的自由流节点定义列表
	 * @param processDefinition
	 * @param currActivityDefinition
	 * @param form
	 */
	public void loadFreeActivitiesByCurrActivity(ProcessDefinitionImpl processDefinition, ActivityImpl currActivityDefinition, WfBusInstanceTaskForm form){
		if(form != null && processDefinition != null && currActivityDefinition != null){
			List<ActivityForm> freeActivities = getFreeActivitiesByCurrActivity(processDefinition, currActivityDefinition);
			form.setFreeActivities(freeActivities);
		}
	}
	
	/**
	 * 获取自由流节点定义列表
	 * @param processDefinition
	 * @param currActivityDefinition
	 * @return
	 */
	public List<ActivityForm> getFreeActivitiesByCurrActivity(ProcessDefinitionImpl processDefinition, ActivityImpl currActivityDefinition){
		if(processDefinition != null && currActivityDefinition != null){
			FreeFlowDefinition freeFlowDefinition = null;
			
			TaskDefinitionImpl taskDefinition = processDefinition.getTaskDefinition(currActivityDefinition.getName());
			if(taskDefinition != null)
				freeFlowDefinition = taskDefinition.getFreeFlowDefinition();
			
			if(freeFlowDefinition != null){

				// 自由流范围
				String scope = freeFlowDefinition.getScope();
				
				// 自由流范围是否仅限于任务节点
				boolean onlyTask = freeFlowDefinition.isOnlyTask();
				
				if(scope.equals(WfConstant.FREE_FLOW_SCOPE_ALL)){
					return getAllActivities(processDefinition, onlyTask);
				}
				else if(scope.equals(WfConstant.FREE_FLOW_SCOPE_RANGE)){
					return getActivitiesByRange(processDefinition, freeFlowDefinition, onlyTask);
				}
				else if(scope.equals(WfConstant.FREE_FLOW_SCOPE_AFTER)){
					// TODO
				}
			}
		}
		
		return null;
	}
	
	/**
	 * 加载自由流范围是全部节点的自由流节点
	 * @param processDefinition
	 * @param workflowInfo
	 * @param onlyTask
	 */
	public List<ActivityForm> getAllActivities(ProcessDefinitionImpl processDefinition, boolean onlyTask){
		if(processDefinition != null){
			List<? extends Activity> activities = processDefinition.getActivities();
			return WfUtils.convertToActivityFormList(processDefinition,activities, onlyTask);
		}
		else
			return null;
	}
	
	/**
	 * 加载自由流范围是指定节点的自由流节点
	 * @param processDefinition
	 * @param freeFlowDefinition
	 * @param workflowInfo
	 * @param onlyTask
	 */
	public List<ActivityForm> getActivitiesByRange(ProcessDefinitionImpl processDefinition, FreeFlowDefinition freeFlowDefinition, boolean onlyTask){
		if(processDefinition != null){
			Map<String, ? extends Activity> allActivities = processDefinition.getActivitiesMap();
			String[] rangeActivityNames = freeFlowDefinition.getActivityRange();
			return WfUtils.convertToActivityFormList(processDefinition,rangeActivityNames, allActivities, onlyTask);
		}
		else
			return null;
	}
	
	/**
	 * 加载当前节点的下一跳转定义列表
	 * @param currActivityDefinition 当前节点定义
	 * @param form
	 */
	public void loadNextTransitionsByCurrActivity(ProcessDefinitionImpl processDefinition, 
			ActivityImpl currActivityDefinition, WfBusInstanceTaskForm form){
		
		if(processDefinition != null && currActivityDefinition != null && form != null){
			List<? extends Transition> outgoingTransitions = currActivityDefinition.getOutgoingTransitions();
			form.setNextTransitions(WfUtils.convertToTransitionFormList(processDefinition,outgoingTransitions));
		}
	}
	
		/**
	 * 获取所有部署的流程定义
	 * @return
	 */
	public List<ProcessDefinition> getAllProcessDefinition(){
		RepositoryService repositoryService = this.processEngine.getRepositoryService();
		List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().list();
		return list;
	}

	/**
	 * 获取系统中按照流程名称独一无二的部署流程定义，忽略版本信息
	 * @return
	 */
	public List<ProcessDefinition> getProcDefIgnoreVersion(){
		List<ProcessDefinition> result = null;
		
		RepositoryService repositoryService = this.processEngine.getRepositoryService();
		List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().orderAsc(ProcessDefinitionQuery.PROPERTY_NAME).orderDesc(ProcessDefinitionQuery.PROPERTY_VERSION).list();
		
		if(list != null && list.size() > 0){
			result = new ArrayList<ProcessDefinition>();
			result.add(list.get(0));
			
			String curProcessName = list.get(0).getName();
			for(int i = 1; i < list.size(); i++){
				if( !curProcessName.equals( list.get(i).getName() )){
					curProcessName = list.get(i).getName();
					
					result.add(list.get(i));
				}
			}
		}
		return result;
	}

	/**
	 * 根据流程定义key获取流程定义
	 * @param key 
	 * @return
	 */
	public List<ProcessDefinition> getProcDefByProcDefKey(String key){
		RepositoryService repositoryService = this.processEngine.getRepositoryService();
		return repositoryService.createProcessDefinitionQuery()
								.processDefinitionKey(key)
								.orderDesc(ProcessDefinitionQuery.PROPERTY_VERSION)
								.list();
	}
	
	/**
	 * 根据流程定义KEY关联删除流程定义
	 * @param key
	 */
	public void deleteProcDefByProcDefKey(String key){
		RepositoryService repositoryService = processEngine.getRepositoryService();
		List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().processDefinitionKey(key).list();
		if(list != null && list.size() > 0){
			for(ProcessDefinition procDef : list){
				repositoryService.deleteDeploymentCascade(procDef.getDeploymentId());
			}
		}
	}
	
	/**
	 * 根据流程定义key获取流程的所有节点
	 * @param procDefKey
	 * @param version
	 * @return list 
	 */
	public List<? extends Activity> getActivitiesByProcDefKeyAndVersion(String procDefKey, Integer version){
		ProcessDefinition processDefinition = this.getProcDefByProcDefKeyAndVersion(procDefKey, version);
		if(processDefinition != null){
			ProcessDefinitionImpl processDefinitionImpl = (ProcessDefinitionImpl)processDefinition;
			return processDefinitionImpl.getActivities();
		}
		return null;
	}
	
	/**
	 * 流程流转（发送）
	 * @param workflowForm
	 */
	public void send(WfBusInstanceTaskForm form){
		TaskService taskService =  processEngine.getTaskService();
		Task task = taskService.getTask(form.getTaskInstDbid().toString());
		long procInstDbid = ((TaskImpl)task).getProcessInstance().getDbid();
		/**  城管委审批add  */
		//保存意见
		this.saveTaskOpinion(form);
		/**  城管委审批end  */
		//保存发送提示消息到变量表
		saveMessageToVariable(task, form);
		
		//多工作项任务
		if(WfUtils.isMultiTask(task)){
			taskService.completeTaskOfMultiTasks(task.getId());
			form.setMessage(MsgConstant.MULTI_TASK_WAITTING);
		}
		
		//普通任务
		else{
			completeTask(form, task);
		}
		//wfBusInstanceService.getInstanceByTaskId(task.getId());
		//加入经办人
		try {
			if("cksa".equals(task.getActivityName())){
				Long taskId=form.getTaskInstDbid();
				Jbpm4HistTask histTask=this.jbpm4HistTaskDao.get(taskId);
				if(histTask!=null){
					String procInsId=histTask.getProcInstId();
					WfBusInstance ins=this.wfBusInstanceService.getByProcInstId(procInsId);
					if(ins!=null){
						WfBusInstanceForm insform=WfBusInstanceConvertor.convertVoToForm(ins);
						insform.setBusMemo6(form.getAssigneeName());
						if(StringUtils.isNotBlank(insform.getBusMemo1())){
							//申请单位不能为空
							wfBusInstanceService.save(insform);
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		
		//查询当前任务完成以后发送给哪些人
		calcSendedAssignees(form, procInstDbid);
	}

	/**
	 * 查询当前任务完成以后发送给哪些人
	 * @param form
	 * @param procInstDbid
	 */
	private void calcSendedAssignees(WfBusInstanceTaskForm form, long procInstDbid){
		if(form != null && (form.getAssigneeName() == null 
				|| form.getAssigneeName().trim().length() == 0)){
			
			List<Jbpm4Task> list = this.jbpm4TaskDao.getRecentTasksByProcInstDbid(procInstDbid);
			if(list != null && list.size() > 0){
				String assigneeNames = "";
				for(int i=0; i<list.size(); i++){
					assigneeNames += list.get(i).getAssigneeName();
					String userCode=list.get(i).getAssignee();//城管委构造短信发送信息
					if ("1".equals(form.getSmsRemind())){
						OmUserForm omUserForm = omUserService.get(userCode);
						if(omUserForm!=null){
							SMToSend sMToSend=new SMToSend();
							sMToSend.setDestAddr(omUserForm.getMobile());//发送目标手机号码
							Date date = new Date();
							sMToSend.setSubTime(date);
							sMToSend.setSendTime(date);
							String smContent ="城管委审批系统：您有案件需及时处理。（请勿回复）";
							sMToSend.setSmContent(smContent);
							this.sMToSendDao.save(sMToSend);
						}
					}
					if(i < list.size()-1)
						assigneeNames += "、";
				}
				form.setAssigneeName(assigneeNames);
			}
		}else{
			if ("1".equals(form.getSmsRemind())){
				OmUserForm omUserForm = omUserService.getUserByName(form.getAssigneeName());
				if(omUserForm!=null){
					SMToSend sMToSend=new SMToSend();
					sMToSend.setDestAddr(omUserForm.getMobile());//发送目标手机号码
					Date date = new Date();
					sMToSend.setSubTime(date);
					sMToSend.setSendTime(date);
					String smContent =omUserForm.getUserName()+"：城管委审批系统您有案件需及时处理。（请勿回复）";
					sMToSend.setSmContent(smContent);
					this.sMToSendDao.save(sMToSend);
				}
			}
		}
	}
	
	/**
	 * 普通任务发送
	 */
	private void completeTask(WfBusInstanceTaskForm form, Task task){
		if(form != null && task != null){
			//更新execution的上一任务ID以实现取回
			TaskImpl taskImpl = (TaskImpl)task;
			ProcessDefinitionImpl processDefinition = this.getProcDefByTaskInstDbid(taskImpl.getDbid());
			Activity curActivity = processDefinition.getActivity(task.getActivityName());
			String assignee = form.getAssignee();
			//
			
			
			//目标节点
			String destActivityName = form.getDestActivityName();
			Activity destActivity = (destActivityName != null && destActivityName.trim().length() > 0) 
										? processDefinition.getActivity(destActivityName) : null;
										
			//当指定目标节点						
			if(destActivity != null){
				TaskDefinitionImpl destTaskDefinition = processDefinition.getTaskDefinition(destActivity.getName());
				
				//按指定下一节点参与者
				if(assignee != null && assignee.trim().length()>0){
					completeTask(task, curActivity, destActivity, destTaskDefinition, assignee);
				}
				
				//按默认任务定义参与者
				else{
					completeTask(task, curActivity, destActivity, destTaskDefinition, null);
				}
			}
			
			//当没有指定目标节点
			else{
				processEngine.getTaskService().completeTask(task.getId());
			}
		}
	}
	
	/**
	 * 按照选择用户处理任务节点
	 * @param busInstanceTask
	 * @param task
	 */
	private void completeTask(Task task, Activity curActivity, Activity destActivity, TaskDefinitionImpl destTaskDefinition, String assignee){
		if(task != null && destActivity != null){
			
			//设置下一人工节点参与者
			if(assignee != null && assignee.trim().length() > 0){
				assignee = assigneeParser.formatAssignee(assignee);
				setTaskAssignee(destTaskDefinition, assignee);
			}
			
			//判断当前节点与目标节点间是否存在跳转
			Transition transition = curActivity.getOutgoingTransitionByDestActivity(destActivity.getName());
			 
			//自由流跳转
			if(transition == null){
				processEngine.getExecutionService().jumpToActivity(task.getExecutionId(), destActivity.getName());
			}
			
			//流向跳转
			else{
				List agentList =  wfServiceEX.getAgentNameById(Long.parseLong(task.getId()));
				processEngine.getTaskService().completeTask(task.getId(), transition.getName());
				setAgentNameById(task.getId(),agentList);
			}
		}
	}
	
	/**
	 * 通过ID，重新保存代理人（由于系统自动清掉代理人，设置为：系统管理员）
	 * @param id
	 */
	public void setAgentNameById(String id, List agentList){		
		if(agentList != null && agentList.size()>0){
			String agent = (String)((Object [])agentList.get(0))[0];
			String agentName = (String)((Object [])agentList.get(0))[1];
			if(StringUtils.isNotBlank(agentName) && !agentName.equals("系统管理员")){
				String sql = "update jbpm4_hist_task t set t.agent_name='"+agentName+"',t.agent='"+agent+"' where t.dbid_='"+id+"'";
				Session session = jbpm4HistTaskDao.getSession();
				SQLQuery query = session.createSQLQuery(sql);
				query.executeUpdate();
			}
		 }		
	}
	
	
	/**
	 * 设置下一人工活动节点的处理人员
	 */
	public void setTaskAssignee(TaskDefinitionImpl taskDefinition, String assignee){
		if(taskDefinition != null && assignee != null && assignee.trim().length() > 0)
			taskDefinition.setAssigneeExpression(Expression.create(assignee));
	}

	/**
	 * 获取历史跟踪信息
	 * @param taskInstDbId
	 */
	public List<TraceRecord> getTraceInfo(Long taskInstDbId){
		if(taskInstDbId != null){
			TaskService taskService = processEngine.getTaskService();
			TaskImpl task = (TaskImpl)taskService.getTask(taskInstDbId.toString());
			
			String processInstanceId = task.getProcessInstance().getId();
			return getTraceInfo(processInstanceId);
		}
		return null;
	}
	
	/**
	 * 获取历史跟踪列表
	 * @param executionId
	 * @return
	 */
	public List<TraceRecord> getTraceInfo(String processInstanceId){
		if(processInstanceId != null){			
			List<HistoryTask> historyTasks = getHistoryTasks(processInstanceId);
			return WfUtils.convertToTraceInfoList(historyTasks);
		}
		return null;
	}
	
	/**
	 * 根据流程实例id获取已经处理的任务
	 */
	public List<HistoryTask> getHistoryTasks(String processInstanceId){
		if(processInstanceId != null){
			
			HistoryService historyService = processEngine.getHistoryService();
			List<HistoryActivityInstance> hisActInsts = historyService.createHistoryActivityInstanceQuery().processInstanceId(processInstanceId).orderAsc("startTime").list();
			
			if(hisActInsts != null && hisActInsts.size() > 0){
				List<HistoryTask> result = new ArrayList();
				for(HistoryActivityInstance hisActInst : hisActInsts){
					if(hisActInst.getType().equals(WfConstant.ACTIVITY_TYPE_TASK)){
						HistoryTaskInstanceImpl hisTaskActInst = (HistoryTaskInstanceImpl)hisActInst;
						HistoryTask historyTask = hisTaskActInst.getHistoryTask();
						if(historyTask != null){
							//以下修改是因为部分处室提出经办人取回案件时候领导没有操作案件，历史记录不应该有领导的记录。
							if(!"cksa".equals(historyTask.getActivityName())){
								if(historyTask.getSignTime()!=null){
									result.add(historyTask);
									HistoryTaskImpl historyTaskImpl = (HistoryTaskImpl)historyTask;
									Set<HistoryTaskImpl> subTasks = historyTaskImpl.getSubTasks();
									if(subTasks != null && subTasks.size() > 0){
										result.addAll(subTasks);
									}
								}
							}else{
								result.add(historyTask);
								HistoryTaskImpl historyTaskImpl = (HistoryTaskImpl)historyTask;
								Set<HistoryTaskImpl> subTasks = historyTaskImpl.getSubTasks();
								if(subTasks != null && subTasks.size() > 0){
									result.addAll(subTasks);
								}
							}
							
						}
					}
				}
				
				return result;
			}
		}
		return null;
	}
	
	/**
	 * 获取历史跟踪信息,先根据节点名称升序，再根据填写意见时间升序来排列
	 * @param taskInstDbid
	 */
	public List<TraceRecord> getTraceInfoOrderByActName(Long taskInstDbid){
		if(taskInstDbid != null){
			TaskService taskService =  processEngine.getTaskService();
			Task task = taskService.getTask(taskInstDbid.toString());
			
			if(task != null)
				return this.getTraceInfoOrderByActName(task.getExecutionId());
		}
		return null;
	}
	/**
	 * 获取历史跟踪列表
	 * @param executionId
	 * @return
	 */
	public List<TraceRecord> getTraceInfoOrderByActName(String executionId){
		if(executionId != null){			
			List<HistoryTask> historyTasks = getHistoryTaskOrderByActName(executionId);
			return  WfUtils.convertToTraceInfoList(historyTasks);
		}
		return null;
	}
	/**
	 * 根据流程实例id获取已经处理的任务
	 */
	public List<HistoryTask> getHistoryTaskOrderByActName(String processInstanceId){
		if(processInstanceId != null){
			HistoryService historyService = processEngine.getHistoryService();
			return historyService.createHistoryTaskQuery().executionId(processInstanceId).orderAsc("activityName").orderAsc("dbid").list();
		}
		return null;
	}
	

	/**
	 * 获取活动节点定义
	 * @param executionId
	 * @param activityName
	 * @return
	 */
	public ActivityImpl getActivityDefinitionByExecutionId(String executionId, String activityName){
		if(executionId != null && activityName != null){
			ExecutionImpl execution = (ExecutionImpl)this.processEngine.getExecutionService().findExecutionById(executionId);
			if(execution != null){
				String processDefinitionId = execution.getProcessDefinitionId();
				ProcessDefinitionImpl processDefinition = getProcDefByProcDefId(processDefinitionId);
				return processDefinition.getActivity(activityName);
			}
		}
		return null;
		
	}
	

	/**
	 * 保存任务的办理人意见
	 * @param task
	 * @param taskOpinion
	 */
	public void saveTaskOpinion(WfBusInstanceTaskForm busInstanceTask){
		if(busInstanceTask != null && busInstanceTask.getTaskInstDbid() != null
				&& busInstanceTask.getHandleComments() != null && busInstanceTask.getHandleComments().trim().length()>0){
			TaskService taskService =  processEngine.getTaskService();
			
			Task task = taskService.getTask(busInstanceTask.getTaskInstDbid().toString());
			if(task != null){
				task.setHandleComments(busInstanceTask.getHandleComments());
				task.setHandleCommentsTime(new Date());
				taskService.saveTask(task);
				
				//同步
				this.syncTaskOpinionToHisTask(task.getId());
			}
		}
	}

	private String getAssigneeNames(TaskDefinitionImpl taskDefinition, Long taskInstDbid){
		if(taskDefinition != null){
			//检查assignee表达式是否为空，如果为空则使用assigneeRange代替
		    WfUtils.replaceRangeForNullAssigneeExp(taskDefinition);
			
			//下一个任务节点assignee表达式
			Expression assigneeExpression = taskDefinition.getAssigneeExpression();
			
			if(assigneeExpression != null){
				String assignee = this.calcJbpmVarExpresssion(assigneeExpression, taskInstDbid);

				if(assignee != null && assignee.trim().length()>0){
					String[] assignees = assigneeParser.parseToOriginalNames(assignee);
					return StringUtils.convertStringArrayToString(assignees, "、");
				}
			}
		}
		return null;
	}

	/**
	 * 计算表达式中的变量实际值
	 * @param exp
	 * @param taskInstDbid
	 * @return
	 */
	private String calcJbpmVarExpresssion(Expression exp, Long taskInstDbid){
		if(exp != null && taskInstDbid != null){
			TaskService taskService = processEngine.getTaskService();
			Task task = taskService.createTaskQuery().dbid(taskInstDbid).uniqueResult();
			try {
				return (String) exp.evaluate(task);
			}catch(RuntimeException e){
				System.out.println("############## 注意错误：无法获取任务ID为" + taskInstDbid + "的变量为" + exp.getExpressionString() + "的值。");
			}
		}
		return null;
	}
	
	/**
	 * 检测选择用户是否符合流程定义标准，不符合返回错误信息，符合，返回null
	 * @param form
	 * @return
	 */
	public ResultForm validateSelectedAssignee(WfBusInstanceTaskForm form){
		
		if(form != null && form.getTaskInstDbid() != null){
			
			TaskService taskService =  processEngine.getTaskService();
			Task task = taskService.getTask(form.getTaskInstDbid().toString());
			
		//	String executionId = task.getExecutionId();
			String destActivityName = form.getDestActivityName();
			String assignee = form.getAssignee();
			
			return validateSelectedAssignees(task, destActivityName, assignee);
		}
		return new ResultForm(false, MsgConstant.VALIDATE_ASSIGNEE_NULL);
	}
	
	/**
	 * 根据实例ID和目标节点获取任务定义和多工作项定义
	 * @param task 
	 * @param destActivityName
	 * @param assignee
	 * @return
	 */
	public ResultForm validateSelectedAssignees(Task task, String destActivityName, String assignee){
		ResultForm result = new ResultForm(true);
		
		if(task != null  
				&& destActivityName != null && destActivityName.trim().length() > 0
				&& assignee != null && assignee.trim().length() > 0){

			String[] userKeys = assigneeParser.convertToUserKeys(assignee);
			
			if(userKeys != null && userKeys.length > 0){
				
				ProcessDefinitionImpl processDefinition = this.getProcDefByTaskInstDbid(((TaskImpl)task).getDbid());
				TaskDefinitionImpl taskDefinition = processDefinition.getTaskDefinition(destActivityName);
				MultiTaskDefinition multiTaskDefinition = taskDefinition.getMultiTaskDefinition();
				
				//多工作项用户
				if(multiTaskDefinition != null){
					result = multiTaskDefinition.getCompleteRule().validate(userKeys);
				}
				//普通用户
				else if(userKeys.length > 1){
					result.setSuccess(false);
					result.setErrMsg(MsgConstant.ONE_MAX + userKeys.length);
				}
			}
			else{
				result.setSuccess(false);
				result.setErrMsg(MsgConstant.NO_USER);
			}
		}
		return result;
	}

	public String getTaskOpinion(Long taskInstDbid) {
		if(taskInstDbid != null){
			Task task = this.processEngine.getTaskService().getTask(taskInstDbid.toString());
			if(task != null)
				return task.getHandleComments();
		}
		return null;
	}
	
	/**
	 * 返回来文人,即返回上一环以及上一环节的处理人
	 * @param form
	 */
//	public void sendToPrevTask(WfBusInstanceTaskForm form){
//		TaskService taskService =  processEngine.getTaskService();
//		Task task = taskService.getTask(form.getTaskInstDbid().toString());
//		
//		Long prevTaskDbId =(Long)this.processEngine.getExecutionService().getVariable(task.getExecutionId(), WfConstant.VAR_SYS_PREV_TASK_ID);
//		List<Jbpm4HistTask> list = this.jbpm4HistTaskDao.getPrivHistTasksById(prevTaskDbId);
//		if(list !=  null && list.size()>0){
//			String assignees = WfUtils.getAssigneesFromHistTaskS(list);
//			String prevActivityName = list.get(0).getActivityName();
//			
//			jumpToPrivTask(task,assignees,prevActivityName);
//		}
//	}
	
	/**
	 * 返回来文人,即返回上一环以及上一环节的处理人,
	 * 返回时候若有流转到上一环节的就用流转,否则用自由流
	 * @param assignees
	 * @param prevActivityName
	 */
	public void jumpToPrivTask(Task task,String assignees,String prevActivityName){
		if(task != null && StringUtils.isNotBlank(assignees) &&StringUtils.isNotBlank(prevActivityName)){
			ProcessDefinitionImpl processDefinition = this.getProcDefByTaskInstDbid(((TaskImpl)task).getDbid());
			
			TaskDefinitionImpl prevTaskDef = processDefinition.getTaskDefinition(prevActivityName);
			prevTaskDef.setAssigneeExpression(Expression.create(assignees));
			
			//判断是否有到上一节点的流转
			Activity currActivity = processDefinition.getActivity(task.getActivityName());
			String transitionName = "to "+prevActivityName;
			Transition tran = currActivity.getOutgoingTransition(transitionName);
			if((tran != null))
				processEngine.getTaskService().completeTask(task.getId(),transitionName);
			else
				processEngine.getExecutionService().jumpToActivity(task.getExecutionId(), prevActivityName);
		}
	}
	
	/**
	 * 根据zip文件流发布流程(zip文件包含流程定义xml文件、流程图png文件)部署流程定义
	 * @param zipInputStream zip文件流
	 * @return
	 * @throws Exception
	 */
	public String deployByZipFileByZipInputStream(ZipInputStream zipInputStream)throws Exception{
		RepositoryService repositoryService = processEngine.getRepositoryService();
		return repositoryService.createDeployment().addResourcesFromZipInputStream(zipInputStream).deploy();
	}
	
		
	/**
	 * 获取待领取任务列表
	 * @param page
	 * @param templateCode
	 * @param userKey
	 * @param params
	 */
	@SuppressWarnings("unchecked")
	public void loadCandidateTasksWithBusInfo(Page page, String templateCode, String userKey, Map<String, String> params){
		
		WfBusTemplateForm form = wfBusTemplateService.getByTemplateCode(templateCode);
		
		if(form != null){
			WfViewConfigForm viewConfig = wfViewConfigService.getByTemplateId(form.getId());
		
			String groupBy = params.get("groupBy");
			String groupDir = params.get("groupDir");
			
			
			//TODO:还要考虑委托人要领取的task
			List<Jbpm4Task> taskList = this.getTasksByUserId(userKey);
		    if(taskList != null && taskList.size()>0){
				StringBuffer sb = new StringBuffer(" and (1=2 ");
				for(Jbpm4Task task:taskList)
				//	sb.append("or jbpm4Task.taskInstDbid="+task.getTaskInstDbid());
					sb.append("or jbpm4Task.DBID_="+task.getTaskInstDbid());
				sb.append(")");
//				
//				String hql = "select distinct " 
//					+ viewConfig.getKeyProperty() + ViewConfigCompiler.PROP_SEPARATOR
//					+ "jbpm4Task.agentName, jbpm4Task.duedate, jbpm4Task.assigneeName, " 
//					+ "jbpm4Task.agentStartDate, jbpm4Task.agentEndDate, jbpm4Task.create, " 
//					+ "jbpm4Task.signTime, wfInstance.wfBusInstanceId, wfInstance.procInstId, jbpm4Task.taskInstDbid," 
//					+ viewConfig.getListProperties()
//					+ " from " + viewConfig.getSelectEntities() + ", WfBusInstance wfInstance, HistoryProcessInstanceImpl procInst,Jbpm4Participant participant,Jbpm4Task jbpm4Task"
//					+ " where " + (viewConfig.getEntitiesJoinClause() == null ? "" : viewConfig.getEntitiesJoinClause())
//					+ viewConfig.getKeyProperty() + "=wfInstance.masterEntityKey and wfInstance.procInstId=procInst.processInstanceId " 
//					+ "and jbpm4Task.procinst=procInst.dbid and wfInstance.templateId=:templateId  "
//					+ sb.toString();
				
				String hql = "select distinct " 
					+ viewConfig.getKeyProperty() + ViewConfigCompiler.PROP_SEPARATOR
					+ "jbpm4Task.AGENT_NAME, jbpm4Task.DUEDATE_, jbpm4Task.ASSIGNEE_NAME, " 
					+ "jbpm4Task.AGENT_START_DATE, jbpm4Task.AGENT_END_DATE, jbpm4Task.CREATE_, " 
					+ "jbpm4Task.SIGN_TIME, wfInstance.WF_BUS_INSTANCE_ID, wfInstance.PROC_INST_ID, jbpm4Task.DBID_," 
					+ viewConfig.getListProperties()
					+ " from " + viewConfig.getSelectEntities() + ", WF_BUS_INSTANCE wfInstance, JBPM4_HIST_PROCINST procInst,jbpm4_participation participant,Jbpm4_Task jbpm4Task"
					+ " where " + (viewConfig.getEntitiesJoinClause() == null ? "" : viewConfig.getEntitiesJoinClause())
					+ viewConfig.getKeyProperty() + "=wfInstance.MASTER_ENTITY_KEY and wfInstance.PROC_INST_ID=procInst.id_ " 
					+ "and jbpm4Task.PROCINST_=procInst.DBID_ and wfInstance.TEMPLATE_ID=:templateId  "
					+ sb.toString();
				
	
				Map<String, Object> values = new HashMap<String, Object>();
				
				if(viewConfig.getWhereClause() != null && viewConfig.getWhereClause().trim().length() > 0 && params != null){
				
					//清除无效参数
					ViewConfigCompiler.clearUseLessParam(params);
					
					
					//计算实际要查询的参数值
					String busEntityName = ViewConfigCompiler.findBusEntityName(viewConfig.getSelectEntities());
					List<SysMetaColumn> queryColumns = getSysMetaColumns(viewConfig.getQueryProperties(), busEntityName);
					
					Map<String, Object> objParams = ViewConfigCompiler.convertToObjectMap(params, queryColumns);
					if(objParams != null && objParams.size() > 0)
						values.putAll(objParams);
					
					
					//解析WHERE语句并生成符合实际查询条件的WHERE子句
					String whereClause = ViewConfigCompiler.parseWhereClause(viewConfig.getWhereClause(), viewConfig.getWhereLogic(), objParams);
					if(whereClause != null && whereClause.trim().length() > 0){
						hql += " and (" + whereClause + ")";
					}
				}
				
				values.put("templateId", form.getId());
				page.setTotalCount(countResult(hql, values));
				
				// 排序
				hql += ViewConfigCompiler.addSortClause(groupBy, groupDir, page.getOrderBy(), page.getOrder(), viewConfig);
				
				
				
				SQLQuery query = wfBusTemplateDao.getSession().createSQLQuery(hql);
				
				query.setProperties(values);
				query.setFirstResult(page.getFirst() - 1);
				query.setMaxResults(page.getPageSize());
				page.setResult(query.list());
				//wfBusTemplateDao.findPageByScrollMode(page, hql, values);
		    }
		}
	}
	/**
	 * 根据userId获取任务领取关系
	 * @param userId
	 * @return
	 */
	private List<Jbpm4Task> getTasksByUserId(String userId){
		List<Jbpm4Task> list = null;
		if(userId != null){
			List<String> prinList = this.wfAgencyService.getPrincipalsByAgent(userId);
			if(prinList == null )
				prinList= new ArrayList<String>();
			prinList.add(userId);
			
			//组装hql语句
			StringBuffer sb = new StringBuffer(" and (1=2 ");
			for(String userKey : prinList){
				sb.append(" or ps.userId='" +userKey +"'");
			}
			sb.append(")");
			
			String hql ="select task from Jbpm4Participant ps,Jbpm4Task task where "  
				+ "ps.task = task.taskInstDbid" +sb.toString();
			
			list = jbpm4TaskDao.find(hql);
		}
		
		return list;
	}
	
	//领取任务
	public void takeTasks(Long[] taskInstDbids, String userId){
		if(userId != null && userId.trim().length() > 0 && taskInstDbids != null && taskInstDbids.length > 0){
			for(Long taskInstDbid : taskInstDbids)
				takeTask(taskInstDbid, userId);
		}
	}
	
	private void takeTask(Long taskId,String userId){
		if(userId != null && taskId != null){
			
			Jbpm4Task task = this.jbpm4TaskDao.get(taskId);
			Jbpm4HistTask histask  = this.jbpm4HistTaskDao.get(taskId);
			
			//task还没有被领取的条件下来领取，即改变task的属性
			if(task != null && task.getAssignee() ==null){
				String assignee = getCanTaskAssignee(taskId,userId);
				
				//更新task和hisTask
				 updateTaskAndHistTask(userId,assignee,task, histask);
				
				//清除待领取关系
				this.participantDao.clearParticipantsByTaskId(taskId.toString());
				
				//增加summary
//				this.addTaskSummary(task);
			}
		}
	}
	
	private void updateTaskAndHistTask(String userId,String assignee,Jbpm4Task task,Jbpm4HistTask histask){
		if(assignee != null && userId != null && task != null && histask != null){
			
			//更新task属性
			task.setDbversion(task.getDbversion() + 1);
			task.setAssignee(assignee);
			String assigneeName = this.assigneeParser.getUserNameByUserKey(assignee);
			task.setAssigneeName(assigneeName);
			
			//改变对应的hisTask的属性
			histask.setDbversion(task.getDbversion() + 1);
			histask.setAssignee(assignee);
			histask.setAssigneeName(assigneeName);
			
			//加载代理信息
			loadAgentInfo(assignee,task,histask);
			
			jbpm4TaskDao.save(task);
			jbpm4HistTaskDao.save(histask);
		}
	}
	/**
	 * 添加任务汇总信息
	 * @param task
	 */
//	private void addTaskSummary(Jbpm4Task task){
//		
//		if(task != null && task.getAssignee() != null){
//			ExecutionService executionService = this.processEngine.getExecutionService();
//		    String templateCode = (String)executionService.getVariable(task.getExecutionId(), WfConstant.VAR_SYS_TEMPLATE);
//		    String busEntityKey = (String)executionService.getVariable(task.getExecutionId(), WfConstant.VAR_SYS_BUS_ENTITY_KEY);
//		    wfTaskSummaryService.addTaskSummary(task, templateCode, busEntityKey);
//		}
//	}
	
	private String getCanTaskAssignee(Long taskId,String userId){
		String assignee = userId;
		if(userId != null && taskId != null){
			String hql = "select participant.userId from Jbpm4Task jbpm4Task,Jbpm4Participant participant,WfAgency agency "
				+" where agency.agent='" + userId + "' and agency.principal= participant.userId " 
				+ "and participant.task = jbpm4Task.taskInstDbid and participant.task='" + taskId +"'";
			
			List<String> list = this.jbpm4TaskDao.find(hql);
			if(list != null && list.size()>0)
				assignee = list.get(0);
		}
		return assignee;
	}
	
	private void loadAgentInfo(String assignee,Jbpm4Task task,Jbpm4HistTask histask){
		if(assignee != null && task != null && histask != null){
			TaskImpl taskImpl = (TaskImpl)this.processEngine.getTaskService().getTask(task.getTaskInstDbid().toString());
	    	String wfDefId = taskImpl.getProcessInstance().getProcessDefinitionId();
	    	WfAgency wfAgency = wfAgencyService.getAgentByJbpm4Task(wfDefId,assignee);
	    	
	    	if(wfAgency != null){
		    	task.setAgent(wfAgency.getAgent());
		    	task.setAgentName(wfAgency.getAgentName());
		    	task.setAgentStartDate(wfAgency.getStartDate());
		    	task.setAgentEndDate(wfAgency.getEndDate());
		    	
		    	histask.setAgent(wfAgency.getAgent());
				histask.setAgentName(wfAgency.getAgentName());
				histask.setAgentStartDate(wfAgency.getStartDate());
				histask.setAgentEndDate(wfAgency.getEndDate());
		    }
		}
	}
	
	/**
	 * 执行jpdl中定义的assigneeRangeHandler
	 * @param taskDefinition
	 * @throws Exception 
	 */
	private String calcAssigneeRange(AssigneeRangeHandler assigneeRangeHandler) {
		if(assigneeRangeHandler != null){
			String className = assigneeRangeHandler.getClassName();
			String method = assigneeRangeHandler.getMethod();
			
			try {
				Class<? extends Object> handlerClass = Class.forName(className);
				Method assignMethod = handlerClass.getMethod(method);
				return (String)assignMethod.invoke(Class.forName(className).newInstance());				
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return null;
	}
	
	/**
	 * 是否有启动流程权限
	 * @param startWfUserKey
	 * @return
	 */
	public boolean hasStartPriv(String startWfUserKey,String wfDefKey,Integer wfDefVersion){
		if(StringUtils.isNotBlank(startWfUserKey) && StringUtils.isNotBlank(wfDefKey) 
				&& wfDefVersion != null){
			ProcessDefinitionImpl processDefinition = (ProcessDefinitionImpl)this.getProcDefByProcDefKeyAndVersion(wfDefKey, wfDefVersion);
			String startPriv = processDefinition.getStartPriv();
			
			//流程没有设置启动权限
			if(startPriv == null)
				return true;
			
			//设置了启动权限
			else{
				String assignees[] = this.assigneeParser.parseToUserKeys(startPriv);
				return WfUtils.containsString(assignees, startWfUserKey);
			}
		}
		return  false;
	}
	/**
	 * 任务的取回
	 * 舒军修改 11年2月21日
	 * @param taskId 历史任务的id
	 */
	public boolean takeBackTask(String processInstanceId, String assignee){
		boolean result = false;
		
		if(processInstanceId != null && assignee != null){
			TaskService taskService = this.processEngine.getTaskService();
			List<Task> curTasks = taskService.createTaskQuery().processInstanceId(processInstanceId).list();
			if(curTasks != null && curTasks.size() > 0){
				TaskImpl firstTask = (TaskImpl)curTasks.get(0);
				HistoryTask hisTask = this.getPrevHistoryTask(firstTask.getExecution());
				
				//任务处理人匹配
				if(hisTask != null && hisTask.getAssignee().equals(assignee)){
					
					//流程是串型的，即四个id相同
					if(isSeriesProcess(firstTask,hisTask)){
						
						//当前是普通任务
						if(curTasks.size() == 1 && firstTask.getSignTime() == null){
							taskService.takeBackTask(firstTask.getId(), hisTask.getId(), "0");
							result = true;
						}
												
//						//当前是多工作项
//						if(curTasks.size() > 1 && WfUtils.isAllTasksNotSigned(curTasks)){
//							taskService.takeBackTask(curTasks, hisTask.getId());
//							result = true;
//						}
					}
				}
			}
		}
		return result;
	}
	
	//流程是串型的，即四个id相同
	private boolean isSeriesProcess(TaskImpl task,HistoryTask hisTask){
		if(task != null && hisTask != null){
			String currentProcInstId = task.getProcessInstance().getId();
			String currentExecutionId = task.getExecutionId();
			
			String hisProcInstId = hisTask.getProcInstId();
			String hisExecutionId = hisTask.getExecutionId();
			if(currentProcInstId.equals(currentExecutionId) && hisProcInstId.equals(hisExecutionId)
					&& currentProcInstId.equals(hisProcInstId))
				return true;
		}
			return false;
	}

	
	/**
	 * 根据系统变量获取上一个HistoryTask
	 * @return
	 */
	private HistoryTask getPrevHistoryTask(ExecutionImpl execution){
		HistoryTask hisTask = null;
		if(execution != null){
				HistoryService historyService = this.processEngine.getHistoryService();
				List<HistoryTask> list = historyService.createHistoryTaskQuery().executionId(execution.getId()).orderDesc("dbid").list();
				if(list != null && list.size() > 1)
					hisTask = list.get(1);
		}
		return hisTask;
	}
	
	/**
	 * 默认回退到上一处理人工环节
	 * @param taskId
	 * @param destActivityName
	 * @return
	 */
	public boolean returnPrevTask(Long taskId){
		if(taskId != null){
			TaskService taskService = this.processEngine.getTaskService();
			TaskImpl task = (TaskImpl)taskService.getTask(taskId.toString());
			ExecutionImpl execution = (ExecutionImpl)task.getExecution();
			String processInstanceId = execution.getProcessInstance().getId();
			
			if(task != null && WfUtils.isMultiTask(task)==false){
				HistoryTaskImpl hisTask = (HistoryTaskImpl)this.getPrevHistoryTask(execution,task);
				if(hisTask != null ){
					String destActivityName = hisTask.getActivityName();
					
					//目标节点不能是当前节点
					if(!task.getActivityName().equals(destActivityName)){
						//是串型流程
						if(isSeriesProcess(task, hisTask)){
							
							TaskDefinitionImpl taskDefinitionImpl = this.getTaskDefinition(processInstanceId, destActivityName);
							
							//设置目标节点任务人
							String taskAssignee = this.getHistoryTaskAssignee(hisTask);
							if("".equals(taskAssignee))
								return false;
							setTaskAssignee(taskDefinitionImpl, taskAssignee);
							
							taskService.takeBackTask(task.getId(), hisTask.getId(),"1");
							return true;
						}
					}
				}
			}
		}
		return false;
	}
	
	/**
	 * 回退的修改
	 * @param execution
	 * @param task
	 * @return
	 */
	private HistoryTask getPrevHistoryTask(ExecutionImpl execution,
			TaskImpl task) {
		HistoryTask hisTask = null;
		if(execution != null){
				HistoryService historyService = this.processEngine.getHistoryService();
				List<HistoryTask> list = historyService.createHistoryTaskQuery().executionId(execution.getId()).orderAsc("dbid").list();
				List<HistoryTask> datas=new ArrayList<HistoryTask>();
				//解决不能多个回退
				Map<String,HistoryTask> map=new LinkedHashMap<String,HistoryTask>();
				//发送了两个以上的环节情况
				for(HistoryTask hist:list){
					if(task.getActivityName().equals(hist.getActivityName())||"cksa".equals(hist.getActivityName())){
						//当前环节不过滤
						map.put(hist.getActivityName(), hist);
					}else if(StringUtils.isNotBlank(hist.getHandleComments()) && 
							!"cksa".equals(hist.getActivityName())){
						//过滤掉没有填意见的记录,窗口收案除外
						map.put(hist.getActivityName(), hist);
					}
				}
				//获取的所有历史任务记录都填写了意见，并且顺序排列了发送的顺序，如窗口-》经办人-》分管审核->主管审核
				//先根据当前环节判断在所有记录中排列的顺序
				int i=0;
				int idx=0;
				for(Map.Entry<String, HistoryTask> entry:map.entrySet()){
					HistoryTask history=entry.getValue();
					if(task.getActivityName().equals(history.getActivityName())){
						idx=i;
					}else{
						i++;
					}
					datas.add(history);
				}
				if(datas.size()>0){
					if(datas != null && datas.size() > 1)
						hisTask = datas.get(idx-1);
					else
						hisTask = datas.get(0);
				}else{
					//这种情况是窗口没有填意见发送给经办人，经办人回退给窗口
					if(datas != null && list.size() > 1)
						hisTask = list.get(1);
					else
						hisTask = list.get(0);
				}
			
		}
		return hisTask;
	
	}

	/**
	 * 动态创建多工作项
	 * @param assignee
	 * @param taskInstDbid
	 */
	public void createSubMultiTasksInRumtime(String assignee, TaskImpl superTask){
		if(assignee != null && assignee.trim().length() > 0 && superTask != null){
			TaskService taskService = this.processEngine.getTaskService();
			taskService.createSubMultiTasksInRumtime(assignee, superTask);
		}
	}
	
	/**
	 * 根据历史任务，获取相应的任务处理者
	 * @param hisTask 历史任务对象
	 * @return 任务处理者，多个人用逗号分开
	 */
	private String getHistoryTaskAssignee(HistoryTaskImpl hisTask){
		String assignee = "";
		
		//判断当前任务是否为主任务，1代表为主任务
		if("1".equals(hisTask.getIsMainTask())){
			assignee = hisTask.getAssignee();
			
			//获取所有子任务人
			Set<HistoryTaskImpl> subHistoryTaskImpls = hisTask.getSubTasks();
			if(subHistoryTaskImpls != null){
				for (HistoryTaskImpl subHistoryTaskImpl : subHistoryTaskImpls) {
					assignee += "," + subHistoryTaskImpl.getAssignee();
				}
			}
		}else{
			//获取当前任务所在的活动节点集合,按创建时间降序排序
			List<HistoryActivityInstance> historyActivityInstances = this.processEngine
																		 .getHistoryService()
																		 .createHistoryActivityInstanceQuery()
																		 .executionId(hisTask.getExecutionId())
																		 .activityName(hisTask.getActivityName())
																		 .orderDesc("startTime")
																		 .list();
			
			if(historyActivityInstances != null && historyActivityInstances.size() > 0){
				//获取当前活动
				HistoryTaskInstanceImpl historyTaskInstance = (HistoryTaskInstanceImpl)historyActivityInstances.get(0);
				
				//获取当前主任务任务人
				HistoryTaskImpl mainHistoryTask = historyTaskInstance.getHistoryTask();
				assignee = mainHistoryTask.getAssignee();
				
				//获取当前子任务人
				Set<HistoryTaskImpl> subHistoryTaskImpls = mainHistoryTask.getSubTasks();
				if(subHistoryTaskImpls != null){
					for (HistoryTaskImpl subHistoryTaskImpl : subHistoryTaskImpls) {
						assignee += "," + subHistoryTaskImpl.getAssignee();
					}
				}
			}
		}
		return assignee;
	}
	
	/**
	 * 根据流程实例ID获取流程定义ID
	 * @return 流程定义ID
	 */
	public String getProcessDfIdByProcessInstenceId(String processInstenceId){
		HistoryProcessInstance historyProcessInstance = processEngine.getHistoryService().createHistoryProcessInstanceQuery().processInstanceId(processInstenceId).uniqueResult();
		String processDefinitionId = historyProcessInstance.getProcessDefinitionId();
		
		return processDefinitionId;
	}

	/**
	 * 保存流程提示信息到变量表
	 */
	public void saveMessageToVariable(Task task, WfBusInstanceTaskForm form){
		if(task != null && form != null){
			
			String executionId = task.getExecutionId();
			ExecutionService executionService = this.processEngine.getExecutionService();
			
			WfSendMessageForm wfSendMessageForm = new WfSendMessageForm();
			if(StringUtils.isNotBlank(form.getSmsRemind()))
				wfSendMessageForm.setSmsRemind(form.getSmsRemind());
			if(StringUtils.isNotBlank(form.getMailRemind()))
				wfSendMessageForm.setMailRemind(form.getMailRemind());
			
			String destActivityName = getDestActivityName(task,form);
			String key = WfConstant.VAR_SYS_JMS + executionId +"_" + destActivityName;
			
			executionService.setVariable(executionId, key,wfSendMessageForm);
		}
	}
	
	//获取目标activityName
	private String getDestActivityName(Task task,WfBusInstanceTaskForm form){
		String destActivityName = null;
		if(task != null && form != null){
			destActivityName = form.getDestActivityName();
			if(destActivityName == null || destActivityName.trim().length()==0){
				ProcessDefinitionImpl processDefinition = this.getProcDefByTaskInstDbid(((TaskImpl)task).getDbid());
				Activity curActivity = processDefinition.getActivity(task.getActivityName());
				Transition outgoingTransition = curActivity.getOutgoingTransitions().get(0);
				if(outgoingTransition != null){
					destActivityName = outgoingTransition.getDestination().getName();
				}
			}
		}
		return destActivityName;
	}
	
	/**
	 * 动态创建多工作项子任务
	 * @param taskInstDbid
	 * @param expression
	 */
	public void createSubMultiTasksInRumtime(Long taskInstDbid, String expression){
		if(taskInstDbid != null && expression != null && expression.trim().length() > 0){
			
		}
	}
	
	/**
	 * 根据executionId获取多工作项的superTaskId
	 * @param executionId
	 * @return
	 */
	public TaskImpl getSuperTaskByExecutionId(String executionId){
		TaskImpl superTask = null;
		if(executionId != null && executionId.trim().length()>0){
			String superTaskId = this.jbpm4TaskDao.getSuperTaskIdByExecutionId(executionId);
			if(superTaskId != null && superTaskId.trim().length()>0){
				superTask = (TaskImpl)this.processEngine.getTaskService().getTask(superTaskId);
			}
		}
		return superTask;
	}
	
	public ProcessEngine getProcessEngine() {
		return processEngine;
	}
	
}
